﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 抽象01
{
    class Program
    {
        static void Main(string[] args)
        {
            // 抽象类不能进行实例化
            // Food f00 = new Food();
            // Food f01 = new Meat();
            Food f02 = new Noodle();
            Food f03 = new Rice();

            People people = new People();
            //people.Eat(f01);
            people.Eat(f02);
            people.Eat(f03);

            //f01.M();
            //f01.M1();
        }
    }

    abstract class Food
    {

        // 父类当中的虚方法只起到一个声明的作用，方法内部的语句，我们没有用到，
        // 那么像这样的方法我们通常声明为抽象方法
        // 抽象方法只起声明作用，所以直接以分号结尾，一定不能带实现的部分（一定不能有方法体）
        // 拥有抽象方法的类叫做抽象类，抽象方法必须包含在抽象类当中，但是抽象类当中可以包含普通方法和虚方法
        // 抽象类独立于抽象方法，也就是说抽象类中可以没有抽象方法，
        // 我们可以为一个类添加abstract关键字修饰，让该类不能被实例化

        // 抽象方法和虚方法的不同：抽象方法一定没有实现的语句，但是虚方法可以有；二者都能在子类中重写；
        // 虚方法可以重写也可以不重写，但是抽象方法一定要重写，即子类一定要重写父类的抽象方法
        
        // 如果抽象类B继承了抽象类A，那么B可以实现A中的抽象方法，也可以不实现A中的抽象方法
        // 子类是普通类，父类是抽象类，如果父类中存在抽象方法的话，那么子类一定要重写父类中的抽象方法

        // 虚方法和抽象方法旨在继承后实现，所以不能使用private进行修饰
        public abstract void ByEat();
        //public virtual void ByEat()
        //{
        //    Console.WriteLine("食物被吃");
        //}

        public void M()
        {
            Console.WriteLine("M方法");
        }
        public virtual void M1()
        {
            Console.WriteLine("虚方法");
        }
    }

    abstract class A
    {
        public int ID { get; set; }
        public void M()
        {

        }
    }

    abstract class Meat : Food
    {
        //public override void ByEat()
        //{
        //    Console.WriteLine("肉被吃");
        //}
        public override void M1()
        {
            Console.WriteLine("Meat.M1()");
        }
    }
    class Noodle : Food
    {
        public override void ByEat()
        {
            Console.WriteLine("面条被吃");
        }
    }
    class Rice : Food
    {
        public override void ByEat()
        {
            Console.WriteLine("米饭被吃");
        }
    }

    class People
    {
        public void Eat(Food food)
        {
            food.ByEat();
        }
    }
}
